home *** CD-ROM | disk | FTP | other *** search
/ Enter 2006 February / enter-2006-02.iso / files / httrack-3.40.exe / {app} / src / htsfilters.c < prev    next >
Encoding:
C/C++ Source or Header  |  2005-05-29  |  10.2 KB  |  329 lines

  1. /* ------------------------------------------------------------ */
  2. /*
  3. HTTrack Website Copier, Offline Browser for Windows and Unix
  4. Copyright (C) Xavier Roche and other contributors
  5.  
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  19.  
  20.  
  21. Important notes:
  22.  
  23. - We hereby ask people using this source NOT to use it in purpose of grabbing
  24. emails addresses, or collecting any other private information on persons.
  25. This would disgrace our work, and spoil the many hours we spent on it.
  26.  
  27.  
  28. Please visit our Website: http://www.httrack.com
  29. */
  30.  
  31.  
  32. /* ------------------------------------------------------------ */
  33. /* File: httrack.c subroutines:                                 */
  34. /*       filters ("regexp")                                     */
  35. /* Author: Xavier Roche                                         */
  36. /* ------------------------------------------------------------ */
  37.  
  38. /* Internal engine bytecode */
  39. #define HTS_INTERNAL_BYTECODE
  40.  
  41.  
  42. // *.gif                  match all gif files 
  43. // *[file]/*[file].exe    match all exe files with one folder structure
  44. // *[A-Z,a-z,0-9,/,?]     match letters, nums, / and ?
  45. // *[A-Z,a-z,0-9,/,?]
  46.  
  47. // *[>10,<100].gif        match all gif files larger than 10KB and smaller than 100KB
  48. // *[file,>10,<100].gif   FORBIDDEN: you must not mix size test and pattern test
  49.  
  50. #include "htsfilters.h"
  51.  
  52. /* specific definitions */
  53. #include "htsbase.h"
  54. #include "htslib.h"
  55. #include <ctype.h>
  56. /* END specific definitions */
  57.  
  58. // α partir d'un tableau de {"+*.toto","-*.zip","+*.tata"} dΘfinit si nom est autorisΘ
  59. // optionnel: taille α contr⌠ller (ou numΘro, etc) en pointeur
  60. //            (en de dΘtection de *size, la taille limite est Θcrite par dessus *size)
  61. // exemple: +-*.gif*[<5] == supprimer GIF si <5KB
  62. int fa_strjoker(int type,char** filters,int nfil,char* nom,LLint* size,int* size_flag,int* depth) {
  63.   int verdict = 0;  // on sait pas
  64.   int i;
  65.   LLint sizelimit=0;
  66.   if (size)
  67.     sizelimit=*size;
  68.   for(i=0;i<nfil;i++) {
  69.     LLint sz;
  70.     int filteroffs = 1;
  71.     if (strncmp(filters[i] + filteroffs, "mime:", 5) == 0) {
  72.       if (type == 0)      // regular filters
  73.         continue;
  74.       filteroffs += 5;    // +mime:text/html
  75.     } else {              // mime filters
  76.       if (type != 0)
  77.         continue;
  78.     }
  79.     if (size)
  80.       sz=*size;
  81.     if (strjoker(nom, filters[i] + filteroffs, &sz, size_flag)) {    // reconnu
  82.       if (size)
  83.       if (sz != *size)
  84.         sizelimit=sz;
  85.       if (filters[i][0]=='+')
  86.         verdict = 1;    // autorisΘ
  87.       else
  88.         verdict = -1;   // interdit
  89.       if (depth)
  90.         *depth=i;
  91.     }
  92.   }
  93.   if (size)
  94.     *size=sizelimit;
  95.   return verdict;
  96. }
  97.  
  98.  
  99. // supercomparateur joker (tm)
  100. // compare a et b (b=avec joker dedans), case insensitive [voir CI]
  101. // renvoi l'adresse de la premiΦre lettre de la chaine
  102. // (cαd *[..]toto.. renvoi adresse de toto dans la chaine)
  103. // accepte les dΘlires du genre www.*.*/ * / * truc*.*
  104. // cet algo est 'un peu' rΘcursif mais ne consomme pas trop de tm
  105. // * = toute lettre
  106. // --?-- : spΘcifique α HTTrack et aux ?
  107. HTS_INLINE char* strjoker(char* chaine,char* joker,LLint* size,int* size_flag) {
  108.   int err=0;
  109.   if (strnotempty(joker)==0) {    // fin de chaine joker
  110.     if (strnotempty(chaine)==0)   // fin aussi pour la chaine: ok
  111.       return chaine;
  112.     else if (chaine[0]=='?')
  113.       return chaine;  // --?-- pour les index.html?Choix=2
  114.     else
  115.       return NULL;    // non trouvΘ
  116.   }
  117.  
  118.   // on va progresser en suivant les 'mots' contenus dans le joker
  119.   // un mot peut Ωtre un * ou bien toute autre sΘquence de lettres
  120.   
  121.   if (strcmp(joker,"*")==0) {  // ok, rien aprΦs
  122.     return chaine;
  123.   }
  124.   
  125.   // 1er cas: jokers * ou jokers multiples *[..]
  126.   if (joker[0]=='*') {  // comparer joker+reste (*toto/..)
  127.     int jmp;    // nombre de caractΦres pour le prochain mot dans joker
  128.     int cut = 0;  // interdire tout caractΦre superflu
  129.     char pass[256];
  130.     char LEFT='[',RIGHT=']';
  131.     int unique=0;
  132.  
  133.     switch(joker[1]) {
  134.       case '[':
  135.         LEFT='[';
  136.         RIGHT=']';
  137.         unique=0;
  138.       break;
  139.       case '(':
  140.         LEFT='(';
  141.         RIGHT=')';
  142.         unique=1;
  143.       break;
  144.     }
  145.  
  146.     if ((joker[1]==LEFT) && (joker[2]!=LEFT)) {  // multijoker (tm)
  147.       int i;
  148.       for(i=0;i<256;i++) pass[i]=0;
  149.  
  150.       // noms rΘservΘs
  151.       if ((strfield(joker+2,"file")) || (strfield(joker+2,"name"))) {
  152.         for(i=0;i<256;i++) pass[i]=1;
  153.         pass[(int) '?'] = 0;
  154.         //pass[(int) ';'] = 0;
  155.         pass[(int) '/'] = 0;
  156.         i=2;
  157.         { int len=(int) strlen(joker);
  158.           while ((joker[i]!=RIGHT) && (joker[i]) && (i<len)) i++; 
  159.         }
  160.       } else if (strfield(joker+2,"path")) {
  161.         for(i=0;i<256;i++) pass[i]=1;
  162.         pass[(int) '?'] = 0;
  163.         //pass[(int) ';'] = 0;
  164.         i=2;
  165.         { int len=(int) strlen(joker);
  166.           while ((joker[i]!=RIGHT) && (joker[i]) && (i<len)) i++;
  167.         }
  168.       } else if (strfield(joker+2,"param")) {
  169.         if (chaine[0]=='?') {  // il y a un paramΦtre juste lα
  170.           for(i=0;i<256;i++) pass[i]=1;
  171.         }  // sinon synonyme de 'rien'
  172.         i=2;
  173.         { int len=(int) strlen(joker);
  174.           while ((joker[i]!=RIGHT) && (joker[i]) && (i<len)) i++;
  175.         }
  176.       } else {
  177.         // dΘcode les directives comme *[A-Z,ΓΩε⌠√,0-9]
  178.         i=2;
  179.         if (joker[i] == RIGHT) {    // *[] signifie "plus rien aprΦs"
  180.           cut = 1;    // caractΦre supplΘmentaire interdit
  181.         } else {
  182.           int len=(int) strlen(joker);
  183.           while ((joker[i]!=RIGHT) && (joker[i]) && (i<len)) {
  184.             if ( (joker[i]=='<') || (joker[i]=='>') ) {  // *[<10]
  185.               int lsize=0;
  186.               int lverdict;
  187.               i++;
  188.               if (sscanf(joker+i,"%d",&lsize) == 1) {
  189.                 if (size) {
  190.                   if (*size>=0) {
  191.                     if (size_flag)
  192.                       *size_flag=1;        /* a jouΘ */
  193.                     if (joker[i-1]=='<')
  194.                       lverdict=(*size<lsize);
  195.                     else
  196.                       lverdict=(*size>lsize);
  197.                     if (!lverdict) {
  198.                       return NULL;        // ne correspond pas
  199.                     } else {
  200.                       *size=lsize;
  201.                       return chaine;  // ok
  202.                     }
  203.                   } else
  204.                     return NULL;          // ne correspond pas
  205.                 } else
  206.                   return NULL;          // ne correspond pas (test impossible)
  207.                 // jump
  208.                 while(isdigit((unsigned char)joker[i])) i++;
  209.               }
  210.             }
  211.             else if (joker[i+1]=='-') {  // 2 car, ex: *[A-Z]
  212.               if ((int) (unsigned char) joker[i+2]>(int) (unsigned char) joker[i]) {
  213.                 int j;
  214.                 for(j=(int) (unsigned char) joker[i];j<=(int) (unsigned char) joker[i+2];j++)
  215.                   pass[j]=1;
  216.                 
  217.               } else err=1;
  218.               i+=3;
  219.             } else {            // 1 car, ex: *[ ]
  220.               if (joker[i+2]=='\\' && joker[i+3] != 0) {  // escaped char, such as *[\[] or *[\]]
  221.                 i++;
  222.               }
  223.               pass[(int) (unsigned char) joker[i]]=1;
  224.               i++;
  225.             }
  226.             if ((joker[i]==',') || (joker[i]==';')) i++;
  227.           }
  228.         }
  229.       }
  230.       // α sauter dans joker
  231.       jmp=i;
  232.       if (joker[i]) jmp++; 
  233.       
  234.       //
  235.     } else {  // tout autoriser
  236.       //
  237.       int i;
  238.       for(i=0;i<256;i++) pass[i]=1;    // tout autoriser
  239.       jmp=1;
  240.       ////if (joker[2]==LEFT) jmp=3;        // permet de recher *<crochet ouvrant>
  241.     }
  242.     
  243.     {
  244.       int i,max;
  245.       char* adr;
  246.  
  247.       // la chaine doit se terminer exactement
  248.       if (cut) {
  249.         if (strnotempty(chaine))
  250.           return NULL;    // perdu
  251.         else
  252.           return chaine;  // ok
  253.       }
  254.  
  255.       // comparaison en boucle, c'est ca qui consomme huhu..
  256.       // le tableau pass[256] indique les caractΦres ASCII autorisΘs
  257.  
  258.       // tester sans le joker (pas ()+ mais ()*)
  259.       if (!unique) {
  260.         if ( (adr=strjoker(chaine,joker+jmp,size,size_flag)) ) {
  261.           return adr;
  262.         }
  263.       }
  264.  
  265.       // tester
  266.       i=0; 
  267.       if (!unique)
  268.         max=strlen(chaine);
  269.       else        /* *(a) only match a (not aaaaa) */
  270.         max=1;
  271.       while(i<(int) max) {
  272.         if (pass[(int) (unsigned char) chaine[i]]) {  // caractΦre autorisΘ
  273.           if ( (adr=strjoker(chaine+i+1,joker+jmp,size,size_flag)) ) {
  274.             return adr;
  275.           }
  276.           i++;
  277.         } else i=max+2;  // sortir
  278.       }
  279.  
  280.       // tester chaεne vide
  281.       if (i!=max+2)  // avant c'est ok
  282.       if ( (adr=strjoker(chaine+max,joker+jmp,size,size_flag)) )
  283.         return adr;
  284.         
  285.       return NULL;  // perdu
  286.     }
  287.  
  288.   } else {  // comparer mot+reste (toto*..)
  289.     if (strnotempty(chaine)) {
  290.       int jmp=0,ok=1;
  291.       
  292.       // comparer dΘbut de joker et dΘbut de chaine
  293.       while((joker[jmp]!='*') && (joker[jmp]) && (ok)) {
  294.         // CI : remplacer streql par une comparaison !=
  295.         if (!streql(chaine[jmp],joker[jmp])) {
  296.           ok=0;  // quitter
  297.         }
  298.         jmp++;
  299.       }
  300.       
  301.       // comparaison ok?
  302.       if (ok) {
  303.         // continuer la comparaison.
  304.         if (strjoker(chaine+jmp,joker+jmp,size,size_flag))
  305.           return chaine;    // retourner 1e lettre
  306.       }
  307.       
  308.     }  // strlen(a)
  309.     return NULL;   
  310.   }  // * ou mot
  311.  
  312.   return NULL;
  313. }
  314.  
  315. // recherche multiple
  316. // exemple: find dans un texte de strcpybuff(*[A-Z,a-z],"*[0-9]"); va rechercher la premiΦre occurence
  317. // d'un strcpy sur une variable ayant un nom en lettres et copiant une chaine de chiffres
  318. // ATTENTION!! Eviter les jokers en dΘbut, o∙ gare au temps machine!
  319. char* strjokerfind(char* chaine,char* joker) {
  320.   char* adr;
  321.   while(*chaine) {
  322.     if ( (adr=strjoker(chaine,joker,NULL,NULL)) ) {  // ok trouvΘ
  323.       return adr;
  324.     }
  325.     chaine++;
  326.   }
  327.   return NULL;
  328. }
  329.